
package com.snapp.util.object.model;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;

import net.sf.json.JSON;
import net.sf.json.xml.XMLSerializer;

import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.output.XMLOutputter;

import com.snapp.util.Bean;
import com.snapp.util.templates.Processor;

/**
 * @author Kile
 *
 */
public abstract class ObjectImpl implements ObjectModel {

	private static final long serialVersionUID = 7029760210107331896L;

	public static final int RESULT_CODE_ERROR = -1;
	public static final int RESULT_CODE_WARNING = 0;
	public static final int RESULT_CODE_SUCCESS = 1;
	
	// result validation
	private int resultCode = RESULT_CODE_SUCCESS;
	private String resultMessage = "ObjectImpl handled successfully";
	
	private String SNAppGlobalName = null;
	
	private boolean readOnly = false;
	private boolean cache = false;
	private boolean encrypt = false;
	
	private Vector<String> propertyNames = null;
	private Vector<String> propertyTypes = null;
	
	private Bean bean = null;
	
	public ObjectImpl() {
		setBean(new Bean());
	}
	
	public abstract String getTableName();

	@SuppressWarnings("unchecked")
	public void fromBean(Bean bean) {
		setSNAppGlobalName(bean.getPropertyString("globalname"));
		setReadOnly((Boolean)bean.getProperty("readonly"));
		//setCache((Boolean)bean.getProperty("cache"));
		//setEncrypt((Boolean)bean.getProperty("encrypt"));
		
		if (!bean.contains("propertyNames")){
			getPropertyNames();
		} else {
			setPropertyNames((Vector<String>)bean.getProperty("propertyNames"));
		}

		if (!bean.contains("propertyTypes")){
			getPropertyTypes();
		} else {
			setPropertyTypes((Vector<String>)bean.getProperty("propertyTypes"));
		}

		getBean().setName(getSNAppGlobalName());

	}
	
	public Processor getTemplateProcessor(ObjectModel obj) {
		return new Processor(obj);
	}
	
	public boolean isReadOnly() {
		return readOnly;
	}

	public void setReadOnly(boolean readOnly) {
		this.readOnly = readOnly;
	}

	public Vector<ObjectModel> list(HashMap<String, String> filterParams) {
		return list(filterParamsToString(filterParams), filterParams);
	}
	
	public Vector<ObjectModel> list(String filter) {
		return list(filter,null);
	}

	public int count(HashMap<String, String> filterParams) {
		return count(filterParamsToString(filterParams), filterParams);
	}
	
	public int count(String filter) {
		return count(filter,null);
	}
	
	public void delete(HashMap<String, String> filterParams) {
		delete(filterParamsToString(filterParams));
	}

	public void load(HashMap<String, String> filterParams) {
		load(filterParamsToString(filterParams));
	}

	public void save() {
		save(null);
	}

	public static Element listToXML(Vector<ObjectModel> list) throws JDOMException {
		Element list_el = new Element("list");
		
		Iterator<ObjectModel> itr = list.iterator();
		while (itr.hasNext()) {
			list_el.addContent(itr.next().toXML());
		}

		return list_el;
	}
	/**
	 * Add the ID name to this object client object synchronization
	 * @return
	 */
	public Element toXML() throws JDOMException {
		Element el = new Element(getBean().getName());
		
		el = getBean().toXML();
		
		if (getIdName() != null) {
			el.setAttribute("SNAppIdName",getIdName());
		} else {
			throw new JDOMException("Null SNAppIdName in ObjectImpl");
		}
		
		if (getSNAppGlobalName() != null) {
			el.setAttribute("SNAppGlobalName",getSNAppGlobalName());
		
		} else {
			throw new JDOMException("Null SNAppGlobalName Name in ObjectImpl");
		}
	
		return el;
	}
	
	/**
	 * 
	 * @return
	 */
	public JSON toJSON() throws Exception {
		JSON json = null;
		
		XMLSerializer xmlSerializer = new XMLSerializer(); 
        json = xmlSerializer.read(new XMLOutputter().outputString(toXML()));
		
        return json;
	}

	public int getResultCode() {
		return resultCode;
	}

	public void setResultCode(int resultCode) {
		this.resultCode = resultCode;
	}

	public String getResultMessage() {
		return resultMessage;
	}

	public void setResultMessage(String resultMessage) {
		this.resultMessage = resultMessage;
	}

	public void setSNAppGlobalName(String snobGlobalName) {
		this.SNAppGlobalName = snobGlobalName;
	}

	public String getSNAppGlobalName() {
		return SNAppGlobalName;
	}

	public boolean isCache() {
		return cache;
	}

	public void setCache(boolean cache) {
		this.cache = cache;
	}

	public boolean isEncrypt() {
		return encrypt;
	}

	public void setEncrypt(boolean encrypt) {
		this.encrypt = encrypt;
	}

	public void setBean(Bean bean) {
		this.bean = bean;
	}
	public Bean getBean() {
		return bean;
	}

	public Vector<String> getPropertyNames() {
		return propertyNames;
	}

	public void setPropertyNames(Vector<String> propertyNames) {
		this.propertyNames = propertyNames;
	}

	public Vector<String> getPropertyTypes() {
		return propertyTypes;
	}

	public void setPropertyTypes(Vector<String> propertyTypes) {
		this.propertyTypes = propertyTypes;
	}

}
